package com.t365.qmm.utils;

/**
 * @author Jane
 * @date 2024-03-04 8:44
 */

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;

public class RedisUtil {

    /**
     * 分布式 jedisPoolResource
     */
    private static final ShardedJedis jedisPoolResource;

    /**
     * 单台 redis
     */
    private static final Jedis jedis;

    static {
        // 1.加载配置文件获取配置信息
        Properties properties = new Properties();
        try {
            properties.load(RedisUtil.class.getClassLoader().getResourceAsStream("t365db.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        /* -------------------------------- 2.常规 redis 配置 ------------------------------------ */
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(10);
        config.setMaxTotal(20);
        config.setMinIdle(5);
        JedisPool jedisPool = new JedisPool(config, properties.getProperty("host"),
                Integer.parseInt(properties.getProperty("port")),
                Integer.parseInt(properties.getProperty("timeout")),
                properties.getProperty("password"));
        jedis = jedisPool.getResource(); // 从连接池中获取一个 Jedis 对象


        /* -------------------------------- 3.分布式 redis 配置 ------------------------------------ */
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);  // 设置最大对象数
        jedisPoolConfig.setMaxIdle(10);  // 最大能够保持空闲状态的对象数
        jedisPoolConfig.setMaxWaitMillis(10000);  // 超时时间
        jedisPoolConfig.setTestOnBorrow(true);  // 在获取连接的时候检查有效性, 默认false
        jedisPoolConfig.setTestOnReturn(true);  // 在返回Object时, 对返回的connection进行validateObject校验

        List<JedisShardInfo> shardInfos = new ArrayList<>();  // 如果是集群，创建一个list
        JedisShardInfo shardInfo1 = new JedisShardInfo(properties.getProperty("host"),
                Integer.parseInt(properties.getProperty("port")));  // 单台 redis 信息
        shardInfo1.setPassword(properties.getProperty("password"));  // 如果需要密码则设置
        shardInfos.add(shardInfo1);  // 添加进list

        ShardedJedisPool shardedJedisPool = new ShardedJedisPool(jedisPoolConfig, shardInfos);  // ShardedJedisPool
        jedisPoolResource = shardedJedisPool.getResource();  // 从连接池中获取一个ShardedJedis对象


    }

    /**
     * 从连接池中获取一个 ShardedJedis 对象
     */
    public static ShardedJedis getShardedJedis() {
        return jedisPoolResource;
    }

    /**
     * 从连接池中获取一个 Jedis 对象
     */
    public static Jedis getJedis(){
        return jedis;
    }
    /* ------------------------------------- key相关操作 -------------------------------------------*/

    /**
     * 用于删除已存在的键,不存在的 key 会被忽略
     */
    public static Long delete(String key) {
        return jedis.del(key);
    }

    /**
     * 用于序列化给定 key ,并返回被序列化的值
     */
    public static byte[] dump(String key){
        return jedis.dump(key);
    }

    /**
     * 用于检查给定 key 是否存在
     */
    public static Boolean exists(String key){
        return jedis.exists(key);
    }

    /**
     * 用于设置 key 的过期时间，key 过期后将不再可用。单位以秒计
     * @param seconds 过期时间-秒
     */
    public static Long expire(String key, Integer seconds){
        return jedis.expire(key, seconds);
    }

    /**
     * 用于以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间。key 过期后将不再可用
     * @param unixTime 秒时间戳：1611567518
     */
    public static Long expireAt(String key, Long unixTime){
        return jedis.expireAt(key, unixTime);
    }

    /**
     * 以毫秒为单位设置 key 的生效时间
     * @param milliseconds 毫秒
     */
    public static Long pexpire(String key, Integer milliseconds){
        return jedis.pexpire(key, milliseconds);
    }

    /**
     * 以毫秒为单位设置 key 的生效时间
     * @param milliseconds 毫秒时间戳：1611567518000
     */
    public static Long pexpireAt(String key, Long milliseconds){
        return jedis.pexpireAt(key, milliseconds);
    }

    /**
     * 用于查找所有符合给定模式 pattern 的 key
     * @param pattern *
     */
    public Set<String> keys(String pattern) {
        return jedis.keys(pattern);
    }

    /**
     * 移除 key 的过期时间，key 将持久保持
     */
    public Long persist(String key) {
        return jedis.persist(key);
    }

    /**
     * Pttl 命令以毫秒为单位返回 key 的剩余过期时间
     */
    public static Long pttl(String key){
        return jedis.pttl(key);
    }

    /**
     * Pttl 命令以秒为单位返回 key 的剩余过期时间
     */
    public static Long ttl(String key){
        return jedis.ttl(key);
    }

    /**
     * 从当前数据库中随机返回一个 key
     */
    public static String randomKey() {
        return jedis.randomKey();
    }

    /**
     * 修改 key 的名称
     * @return 改名成功时提示 OK ，失败时候返回一个错误。
     */
    public static String rename(String oldKey, String newKey) {
        return jedis.rename(oldKey, newKey);
    }

    /**
     * 用于在新的 key 不存在时修改 key 的名称
     * @return 修改成功时，返回 1 。 如果 NEW_KEY_NAME 已经存在，返回 0
     */
    public Long renameIfAbsent(String oldKey, String newKey) {
        return jedis.renamenx(oldKey, newKey);
    }

    /**
     * 用于返回 key 所储存的值的类型
     * @return 返回 key 的数据类型，数据类型有: none (key不存在)、string (字符串)、list (列表)、set (集合)、zset (有序集)、hash (哈希表)
     */
    public static String type(String key) {
        return jedis.type(key);
    }



}